package com.chzu.service.Impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chzu.config.security.service.UserDetailServiceImpl;
import com.chzu.mapper.SysRoleMapper;
import com.chzu.mapper.SysUserMapper;
import com.chzu.pojo.SysRole;
import com.chzu.pojo.SysUser;
import com.chzu.pojo.vo.LoginVo;
import com.chzu.result.JsonResult;
import com.chzu.result.PageResult;
import com.chzu.result.QueryInfo;
import com.chzu.service.SysUserService;
import com.chzu.utils.JwtTokenUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import javax.annotation.Resource;
import java.security.Principal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author lz
 * @Version 1.0
 * @Company 滁州大健康与养老产业研究院
 * @ClassName SysUserServiceImpl
 * @Description
 * @Date 2022/01/27 14:35
 */
@Service
@Slf4j
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Resource
    private  SysUserMapper sysUserMapper;
    @Autowired
    private UserDetailServiceImpl userDetailsService;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    @Resource
    private SysUserService userService;
    @Resource
    private  SysRoleMapper roleMapper;


    @Override
    public JsonResult<Object> login(LoginVo loginVo) {
        log.info("1. 开始登录");
        UserDetails userDetails = userDetailsService.loadUserByUsername(loginVo.getUsername());
        if (userDetails == null || !passwordEncoder.matches(loginVo.getPassword(), userDetails.getPassword())) {
            return JsonResult.fail("账号或密码错误，请重新输入");
        }
        if (!userDetails.isEnabled()) {
            return JsonResult.fail("账号已经被禁用，请联系管理员");
        }
        log.info("登录成功，在security对象中存入登陆信息");
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        log.info("根据登录信息获取token");
        String token = jwtTokenUtil.generateToken(userDetails);
        Map<String, Object> map = new HashMap<>(2);
        map.put("tokenHead", tokenHead);
        map.put("token", token);
        return JsonResult.ok(map);
    }

    /**
     * 微信小程序登录
     * @param openid 小程序的唯一标识
     * @return 结果
     */
    @Override
    public JsonResult<Object> miniLogin(String openid) {
        log.info("1. 微信小程序开始登录");
        // 判断用户是否存在
        boolean res = userService.isExistenceUser(openid);
        if (!res) {
            // 添加用户
//            int u = userService.insertWxUser(openid);
            //            if (u < 0) {
//                return JsonResult.fail("用户创建失败");
//            }
            // 为添加的用户分配角色
            int r = userService.assignRoles(openid);
        }
        UserDetails userDetails = null;
        userDetails = userDetailsService.loadUserByUsername(openid);
        if (userDetails == null) {
            sysUserMapper.insertOpenid(openid);
            userDetails = userDetailsService.loadUserByUsername(openid);
        }
        if (!userDetails.isEnabled()) {
            return JsonResult.fail("账号已经被禁用，请联系管理员");
        }
        log.info("微信小程序登录成功，在security对象中存入登陆信息");
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        log.info("根据登录信息获取token");
        String token = jwtTokenUtil.generateToken(userDetails);
        Map<String, Object> map = new HashMap<>(4);
        map.put("tokenHead", tokenHead);
        map.put("token", token);
        map.put("userInfo", userDetails);
        map.put("openid",openid);
        return JsonResult.ok(map);
    }

    /**
     * 根据openid更新用户信息
     * @param user 用户对象
     * @return 受影响的行数
     */
    @Override
    public JsonResult<Object> updateInfo(SysUser user) {
        if(user.getOpenId() == null || "".equals(user.getOpenId())) {
            return JsonResult.fail("请传递小程序的唯一标识");
        }
        int res = sysUserMapper.updateInfo(user);
        return JsonResult.ok("用户信息更新成功");
    }


    /**
     * 判断用户是否存在
     * @param value 用户标识
     * @return 结果
     */
    @Override
    public boolean isExistenceUser(String value) {
        int res = sysUserMapper.isExistenceUser(value);
        if (res > 0) {
            return true;
        } else {
            return false;
        }
    }


    /**
     *  根据用户信息查询用户
     * @param username 用户名
     * @return
     */
    @Override
    public SysUser findByUsername(String username) {
        return sysUserMapper.finByUsername(username);
    }

    /**
     *  根据小程序的唯一标识创建用户
     * @param code 小程序唯一标识
     * @return 受影响的行数
     */
    @Override
    public int insertWxUser(String code) {
        return sysUserMapper.insertWxUser(code);
    }

    /**
     *  根据用户标识为用户分配角色
     * @param value 用户标识
     * @return 受影响行数
     */
    @Override
    public int assignRoles(String value) {
        return sysUserMapper.assignRoles(value);
    }


    /**
     * 分页查询用户信息
     * @param queryInfo
     * @return 分页数据
     */
    @Override
    public JsonResult<Object> findPage(QueryInfo queryInfo) {
        PageHelper.startPage(queryInfo.getPageNumber(),queryInfo.getPageSize());
        Page<SysUser> page = sysUserMapper.findPage(queryInfo.getQueryString());
        long total = page.getTotal();
        List<SysUser> result = page.getResult();
        result.forEach(item -> {
            item.setRoles(sysUserMapper.findRoles(item.getId()));
            item.setPassword(null);
        });
        return PageResult.pageResult(result,total);
    }

    /**
     * 添加用户信息
     * @param user 用户
     */
    @Transactional
    @Override
    public JsonResult<Object> insertUser(SysUser user) {
        SysUser sysUser = sysUserMapper.finByUsername(user.getUsername());
        if (sysUser != null) {
            return JsonResult.fail("用户名已经存在");
        }
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        sysUserMapper.insertUser(user);
        List<SysRole> roles = user.getRoles();
        if (roles.size() > 0) {
            roles.forEach(item -> {
                sysUserMapper.insertUserRoles(user.getId(), item.getId());
            });
        }
        return JsonResult.ok("用户添加成功");
    }

    /**
     *  修改用户信息
     * @param user 用户
     */
    @Override
    public JsonResult<Object> updateUser(SysUser user) {
        sysUserMapper.deleteRolesByUserId(user.getId());
        List<SysRole> roles = user.getRoles();
        if (roles.size() > 0) {
            roles.forEach(item -> {
                sysUserMapper.insertUserRoles(user.getId(), item.getId());
            });
            user.setPassword(passwordEncoder.encode(user.getPassword()));
            sysUserMapper.updateUser(user);
        }
        return JsonResult.ok("用户修改成功");
    }

    /**
     *  删除用户信息
     * @param id 用户id
     */
    @Override
    public JsonResult<Object> deleteUser(Integer id) {
        SysUser sysUser = sysUserMapper.findById(id);
        if(sysUser == null) {
            return JsonResult.fail("用户id不存在");
        }
        sysUserMapper.deleteRolesByUserId(id);
        sysUserMapper.deleteUser(id);
        return JsonResult.ok("用户信息删除成功");
    }


}
